package com.flux.ui.activity

import android.app.Activity
import android.app.ActivityManager
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Color
import android.os.*
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v7.app.AppCompatActivity
import android.util.DisplayMetrics
import android.util.SparseArray
import android.view.*
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import android.widget.Toast

import com.flux.Consts

import com.flux.ui.widget.photoview.PhotoView
import com.flux.utils.ImageUtil
import com.flux.utils.LogUtil

import java.lang.ref.WeakReference
import java.util.ArrayList

/**
 * Created on 2016/1/16.
 *
 * @author MartinKent
 */
open class FBaseActivity : AppCompatActivity() {

    private val viewCacher = SparseArray<View>(20)

    private var inflater: LayoutInflater? = null
    private var onCreateExecuted = false

    /**
     * 程序是否在后台运行
     */
    private var isAppBackground: Boolean = false

    /**
     * isJugingBackground
     */
    private var isJugingBackground = false

    private var fragmentManager: FragmentManager? = null

    private var imagePreviewDialog: PhotoView? = null

    private var imagePreviewDialogBitmap: Bitmap? = null

    private val handler = ActivityHandler(this)

    val screenWide: Int
        get() {
            return if (Consts.SCREEN_WIDE == -1) {
                LogUtil.d("Consts.SCREEN_WIDE==" + "no get wide")
                -1
            } else {
                LogUtil.d("Consts.SCREEN_WIDE==" + Consts.SCREEN_WIDE)
                Consts.SCREEN_WIDE
            }

        }

    val screenHeight: Int
        get() {
            return if (Consts.SCREEN_HEIGHT == -1) {
                LogUtil.d("Consts.SCREEN_WIDE==" + "no get height")
                -1
            } else {
                LogUtil.d("Consts.SCREEN_HEIGHT==" + Consts.SCREEN_HEIGHT)
                Consts.SCREEN_HEIGHT
            }
        }

    val screenDensity: Float
        get() {
            return if (Consts.SCREEN_DENSITY == -1f) {
                LogUtil.d("Consts.SCREEN_DENSITY==" + "no get density")
                -1f
            } else {
                LogUtil.d("Consts.SCREEN_DENSITY==" + Consts.SCREEN_DENSITY)
                Consts.SCREEN_DENSITY
            }
        }

    /**
     * getActivityStartExtra
     *
     * @return 字符串数组类型的附加参数
     */
    val activityStartExtra: Array<String>?
        get() = if (null == intent) {
            null
        } else intent.getStringArrayExtra(Consts.ACTIVITY_START_STRING_EXTRAS)

    private var toast: Toast? = null

    private var confirmDialog: Dialog? = null
    private var settedOnConfirmDialogDismissListener: DialogInterface.OnDismissListener? = null
    private val onConfirmDialogDismissListener = DialogInterface.OnDismissListener { dialog ->
        if (null != settedOnConfirmDialogDismissListener) {
            settedOnConfirmDialogDismissListener!!.onDismiss(dialog)
        }
        confirmDialog = null
    }

    fun showImagePreviewDialog(path: String) {
        LogUtil.enter(path)
        if (null != imagePreviewDialog) {
            if (null != imagePreviewDialog!!.parent) {
//                removeInRootView(imagePreviewDialog)
            }
            imagePreviewDialog = null
        }
        imagePreviewDialog = PhotoView(this)
        imagePreviewDialog!!.setBackgroundColor(Color.argb(128, 0, 0, 0))
        imagePreviewDialog!!.visibility = View.GONE
        imagePreviewDialog!!.scaleType = ImageView.ScaleType.CENTER_INSIDE
//        addInRootView(imagePreviewDialog!!, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
        imagePreviewDialog!!.setOnViewTapListener { _, _, _ -> hideImagePreviewDialog() }

        val bitmap = ImageUtil.getBitmapFromFile(path)
        imagePreviewDialog!!.setImageBitmap(bitmap)

        imagePreviewDialog!!.visibility = View.VISIBLE
    }

    fun showImagePreviewHttpDialog(path: ArrayList<String>, selected: Int) {
        val intent = Intent(this, FImagePreviewActivity::class.java)
        intent.putExtra(Consts.Keys.image_preview_activity_source, path)
        intent.putExtra(Consts.Keys.dp_image_preview_activity_selected_pos, selected)
        startActivity(intent)
    }

    fun hideImagePreviewDialog(): Boolean {
        if (null != imagePreviewDialog && View.VISIBLE == imagePreviewDialog!!.visibility) {
            val anim = AnimationUtils.loadAnimation(this, android.R.anim.fade_out)
            anim.setAnimationListener(object : Animation.AnimationListener {
                override fun onAnimationStart(animation: Animation) {

                }

                override fun onAnimationEnd(animation: Animation) {
                    imagePreviewDialog!!.visibility = View.GONE
//                    removeInRootView(imagePreviewDialog)
                    imagePreviewDialog = null
                }

                override fun onAnimationRepeat(animation: Animation) {

                }
            })
            imagePreviewDialog!!.startAnimation(anim)

            if (null != imagePreviewDialogBitmap) {
                if (!imagePreviewDialogBitmap!!.isRecycled) {
                    imagePreviewDialogBitmap!!.recycle()
                }
                imagePreviewDialogBitmap = null
            }
            return true
        }
        return false
    }

    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
        return hideImagePreviewDialog() || super.dispatchKeyEvent(event)
    }

    protected fun hideSoftKeyboard(view: View) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(view.windowToken, 0)
    }

    /**
     * handleMessage
     *
     * @param msg msg
     */
    protected open fun handleMessage(msg: Message) {

    }

    /**
     * sendEmptyMessage
     *
     * @param what what
     */
    protected fun sendEmptyMessage(what: Int) {
        handler.sendEmptyMessage(what)
    }

    /**
     * sendEmptyMessageDelayed
     *
     * @param what  what
     * @param delay delay
     */
    protected fun sendEmptyMessageDelayed(what: Int, delay: Long) {
        handler.sendEmptyMessageDelayed(what, delay)
    }

    /**
     * sendMessage
     *
     * @param msg msg
     */
    protected fun sendMessage(msg: Message) {
        handler.sendMessage(msg)
    }

    /**
     * sendMessageDelayed
     *
     * @param msg   msg
     * @param delay 延迟时间
     */
    protected fun sendMessageDelayed(msg: Message, delay: Long) {
        handler.sendMessageDelayed(msg, delay)
    }

    /**
     * removeMessage
     *
     * @param what 编号
     */
    protected fun removeMessage(what: Int) {
        handler.removeMessages(what)
    }

    /**
     * post
     *
     * @param runnable runnable
     */
    fun post(runnable: Runnable) {
        handler.post(runnable)
    }

    /**
     * postDelayed
     *
     * @param runnable    runnable
     * @param delayMillis delayMillis
     */
    fun postDelayed(runnable: Runnable, delayMillis: Long) {
        handler.postDelayed(runnable, delayMillis)
    }

    /**
     * removeCallbacks
     *
     * @param r Runnable
     */
    protected fun removeCallbacks(r: Runnable) {
        handler.removeCallbacks(r)
    }

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val metric = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(metric)
        Consts.SCREEN_WIDE = metric.widthPixels     // 屏幕宽度（像素）
        Consts.SCREEN_HEIGHT = metric.heightPixels   // 屏幕高度（像素）
        Consts.SCREEN_DENSITY = metric.density      // 屏幕密度（0.75 / 1.0 / 1.5）

        inflater = layoutInflater
        onCreateExecuted = true
        fragmentManager = supportFragmentManager
    }

    override fun onResume() {
        super.onResume()
        if (onCreateExecuted) {
            onFirstResume()
        } else {
            onAnotherResume()
        }
    }

    /**
     * onFirstResume
     */
    protected fun onFirstResume() {

    }

    /**
     * onAnotherResume
     */
    protected fun onAnotherResume() {
        val task = object : AsyncTask<Any, Int, Any>() {
            override fun doInBackground(params: Array<Any>): Any? {
                while (isJugingBackground) {
                    try {
                        Thread.sleep(50)
                    } catch (e: InterruptedException) {
                        e.printStackTrace()
                    }

                }
                return null
            }

            override fun onPostExecute(o: Any?) {
                super.onPostExecute(o)
                if (isAppBackground) {
                    isAppBackground = false
                    onReturnFromOtherApp()
                } else {
                    onReturnFromSelf()
                }
            }
        }
        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
    }

    /**
     * onReturnFromSelf
     */
    protected fun onReturnFromSelf() {

    }

    /**
     * onReturnFromOtherApp
     */
    protected fun onReturnFromOtherApp() {

    }

    /**
     * onStop
     */
    override fun onStop() {
        super.onStop()
        onCreateExecuted = false

        val task = object : AsyncTask<Any, Int, Boolean>() {
            override fun onPreExecute() {
                super.onPreExecute()
                isJugingBackground = true
            }

            override fun doInBackground(params: Array<Any>): Boolean {
                return jugeBackground()
            }

            override fun onPostExecute(o: Boolean) {
                super.onPostExecute(o)
                isAppBackground = o
                isJugingBackground = false
            }
        }
        task.execute()
    }

    /**
     * jugeBackground
     *
     * @return jugeBackground
     */
    private fun jugeBackground(): Boolean {
        val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val appProcesses = activityManager.runningAppProcesses ?: return false
        appProcesses.filter { it.processName == packageName }.forEach { return it.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND }
        return false
    }

    /**
     * inflate
     *
     * @param layoutResId 布局文件ID
     * @return 控件
     */
    fun inflate(layoutResId: Int): View {
        return inflater!!.inflate(layoutResId, null)
    }

    /**
     * startActivity
     *
     * @param cls    目标类
     * @param extras 附加参数
     */
    fun startActivity(cls: Class<*>, vararg extras: String) {
        val intent = Intent(this, cls)
        intent.putExtra(Consts.ACTIVITY_START_STRING_EXTRAS, extras)
        super.startActivity(intent)
    }

    /**
     * startActivityForResult
     *
     * @param cls         目标类
     * @param requestCode 请求代码
     * @param data        附加参数
     */
    fun startActivityForResult(cls: Class<*>, requestCode: Int, vararg data: String) {
        val intent = Intent(this, cls)
        intent.putExtra(Consts.ACTIVITY_START_STRING_EXTRAS, data)
        super.startActivityForResult(intent, requestCode)
    }

    /**
     * finish
     *
     * @param resultCode 结果代码
     * @param data       返回值
     */
    fun finish(resultCode: Int, vararg data: String) {
        val intent = Intent()
        intent.putExtra(Consts.ACTIVITY_RESULT_STRING_EXTRAS, data)
        setResult(resultCode, intent)
        finish()
    }

    /**
     * startActivityWithTaskCleared
     *
     * @param cls    目标类
     * @param extras 附加参数
     */
    open fun startActivityWithTaskCleared(cls: Class<*>, vararg extras: String) {
        val intent = Intent(this, cls)
        intent.putExtra(Consts.ACTIVITY_START_STRING_EXTRAS, extras)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        super.startActivity(intent)
        finish()
    }

    /**
     * onActivityResult
     *
     * @param requestCode 请求代码
     * @param resultCode  结果代码
     * @param data        返回值
     */
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        LogUtil.enter("requestCode=" + requestCode + ",resultCode=" + resultCode + ",data=" + (data?.toString()
                ?: "null"))
        val fragments = supportFragmentManager.fragments
        fragments?.filter { null != it }?.forEach { it.onActivityResult(requestCode, resultCode, data) }
        if (null != data && data.hasExtra(Consts.ACTIVITY_RESULT_STRING_EXTRAS)) {
            onActivityResult(requestCode, resultCode, data.getStringArrayExtra(Consts.ACTIVITY_RESULT_STRING_EXTRAS))
        } else {
            onActivityResult(requestCode, resultCode, null as Array<String>?)
        }
    }

    /**
     * onActivityResult
     *
     * @param requestCode 请求代码
     * @param resultCode  结果代码
     * @param data        返回值
     */
    protected open fun onActivityResult(requestCode: Int, resultCode: Int, data: Array<String>?) {

    }

    /**
     * replaceFragment
     *
     * @param container 容器
     * @param fragment  fragment
     * @param tag       tag
     */
    fun replaceFragment(container: Int, fragment: Fragment, vararg tag: String) {
        if (isEmpty(tag)) {
            fragmentManager!!.beginTransaction().replace(container, fragment).commit()
        } else {
            fragmentManager!!.beginTransaction().replace(container, fragment, tag[0]).commit()
        }
    }

    /**
     * showToast
     *
     * @param resId      字符串资源ID
     */
    fun showToast(resId: Int) {
        showToast(getString(resId))
    }

    /**
     * showToast
     *
     * @param msg        显示字符串
     */
    fun showToast(msg: String) {
        if (null == toast) {
            toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT)
            toast!!.show()
        } else {
            toast!!.setText(msg)
            toast!!.show()
        }
    }

    /**
     * isEmpty
     *
     * @param src 字符串
     * @return 是否为空
     */
    fun isEmpty(src: String?): Boolean {
        return null == src || src.isEmpty()
    }

    /**
     * isEmpty
     *
     * @param src 数组
     * @param <T> 通配类型
     * @return 是否为空
     */
    fun <T> isEmpty(src: Array<T>?): Boolean {
        return null == src || src.isEmpty()
    }

    /**
     * isEmpty
     *
     * @param src 列表
     * @return 是否为空
     */
    fun isEmpty(src: List<*>?): Boolean {
        return null == src || src.isEmpty()
    }

    /**
     * isEmpty
     *
     * @param src 图
     * @return 是否为空
     */
    fun isEmpty(src: Map<*, *>?): Boolean {
        return null == src || src.isEmpty()
    }

    fun stringListToString(list: List<String>): String {
        LogUtil.d("list: $list")
        var rt = ""
        for (item in list) {
            rt += item.trim { it <= ' ' } + ","
        }
        if (rt.endsWith(",")) {
            rt = rt.substring(0, rt.length - ",".length)
        }
        return rt
    }

    fun hideConfirmDialog() {
        if (null != confirmDialog) {
            confirmDialog!!.dismiss()
        }
    }

    fun showConfirmDialog(activity: Activity, content: String, negativeContent: String,
                          positiveContent: String, onNegativeClick: DialogInterface.OnClickListener,
                          onPositiveClick: DialogInterface.OnClickListener,
                          onDismissListener: DialogInterface.OnDismissListener?) {
        hideConfirmDialog()

        settedOnConfirmDialogDismissListener = onDismissListener
        confirmDialog = AlertDialog.Builder(activity)
                .setMessage(content)
                .setNegativeButton(negativeContent, onNegativeClick)
                .setPositiveButton(positiveContent, onPositiveClick)
                .create()
        confirmDialog!!.setOnDismissListener(onConfirmDialogDismissListener)
        confirmDialog!!.show()
    }

    private class ActivityHandler internal constructor(activity: FBaseActivity) : Handler() {
        private val mActivity: WeakReference<FBaseActivity> = WeakReference(activity)

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            val activity = mActivity.get()
            activity?.handleMessage(msg)
        }
    }
}